package com.minelx.sqlstructures.statements.parse.select;

import com.minelx.sequence.core.Match;
import com.minelx.sequence.core.ReturnMatcher;
import com.minelx.sequence.core.StringScanner;
import com.minelx.sqlstructures.common.parse.JoinMatcher;
import com.minelx.sqlstructures.statements.clause.SelectClauseBuilder;
import com.minelx.sqlstructures.statements.clause.Field;

import java.util.Set;

import static java.util.stream.Collectors.toSet;

public class SelectClauseBuilderParser implements ReturnMatcher<SelectClauseBuilder, StringScanner> {
	private static final String SELECT = "SELECT";

	private static final String FROM = "FROM";

	private final ReturnMatcher<String, StringScanner> tableNameMatcher;

	private final JoinMatcher<Field> fieldMatcher;

	public SelectClauseBuilderParser() {
		// FIXME 2021/6/24  wait for me!!!    field like: a.*  will not work
		fieldMatcher = new JoinMatcher<>(Match.content(", "), new FieldMatcher());
		tableNameMatcher = new TableNameMatcher();
	}

	@Override
	public boolean isMatch(StringScanner source) {
		source.trim();
		return source.exists(SELECT);
	}

	@Override
	public SelectClauseBuilder onMatched(StringScanner source) {
		source.goes(SELECT);
		source.trim();
		Set<Field> fields = source.stream(fieldMatcher).collect(toSet());
		source.trim();
		source.goes(FROM);
		source.trim();
		String tableName = tableNameMatcher.get(source).orElseThrow(RuntimeException::new);
		SelectClauseBuilder result = new SelectClauseBuilder(tableName);
		fields.forEach(result::add);
		return result;
	}
}
